package models

import (
	"fmt"
	"gitchina/kly_mall/errors"
	"gitchina/kly_mall/util"
	"strconv"
)

var ID_Shard = 1
var ID_Ver = 1
var ID_Member_Category = 1
var ID_Carrier_Pub_Category = 2
var ID_Line_Pub_Category = 3
var ID_Waybill_Category = 4
var ID_InvoiceAddr_Category = 5
var ID_Linebill_Category = 6
var ID_Payment_Category = 7

type ID string

func (i *ID) Encode(shard, ver, category int, id int64) {
	checksum := util.Compute(fmt.Sprintf("%d%d%d%d", shard, ver, category, id))
	*i = ID(fmt.Sprintf("%s%s%s%s%s",
		fmt.Sprintf("%02s", strconv.FormatInt(int64(shard), 36)),
		fmt.Sprintf("%s", strconv.FormatInt(int64(ver), 36)),
		fmt.Sprintf("%02s", strconv.FormatInt(int64(category), 36)),
		fmt.Sprintf("%06s", strconv.FormatInt(id, 36)),
		fmt.Sprintf("%04s", strconv.FormatInt(int64(checksum), 36))))
}

func (i ID) Decode() (shard, ver, category, id int64, err error) {
	if len(i) != 15 {
		err = errors.Raw(errors.MBR_INVAID)
	} else {
		var checksum int64
		seg1 := string(i[0:2])
		seg2 := string(i[2:3])
		seg3 := string(i[3:5])
		seg4 := string(i[5:11])
		seg5 := string(i[11:])
		if shard, err = strconv.ParseInt(seg1, 36, 32); err != nil {
			err = errors.Raw(errors.MBR_INVAID)
			return
		}
		if ver, err = strconv.ParseInt(seg2, 36, 32); err != nil {
			err = errors.Raw(errors.MBR_INVAID)
			return
		}
		if category, err = strconv.ParseInt(seg3, 36, 32); err != nil {
			err = errors.Raw(errors.MBR_INVAID)
			return
		}
		if id, err = strconv.ParseInt(seg4, 36, 32); err != nil {
			err = errors.Raw(errors.MBR_INVAID)
			return
		}
		if checksum, err = strconv.ParseInt(seg5, 36, 32); err != nil {
			err = errors.Raw(errors.MBR_INVAID)
			return
		}
		if checksum != int64(util.Compute(fmt.Sprintf("%d%d%d%d", shard, ver, category, id))) {
			err = errors.Raw(errors.MBR_INVAID)
		}
	}
	return
}
